package hacky.filebased.agent;

import java.io.Closeable;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;

public class FileUtilities {
    public static byte[] readFileFully(File fileWritten) {
        RandomAccessFile randomAccessFile = null;

        try {
            randomAccessFile = new RandomAccessFile(fileWritten, "r");
            byte[] fullClassFile = allocateByteArrayToHoldClassFile(randomAccessFile);
            randomAccessFile.readFully(fullClassFile);
            return fullClassFile;
        } catch (Exception e) {
            e.printStackTrace(System.err);
            return null;
        } finally {
            closeIgnoringIoException(randomAccessFile);
        }
    }

    public static File writeClassFile(File tempDirectory, String fullyQualifiedClassName,
            byte[] classfileBuffer) throws FileNotFoundException, IOException {
        File classFile = generateDestinationFile(fullyQualifiedClassName, tempDirectory);
        writeBytesToFile(classfileBuffer, classFile);
        return classFile;
    }

    static File generateDestinationFile(String fullyQualifiedClassName, File tempDirectory) {
        String className = fullyQualifiedClassName.replaceAll(".*/", "");
        return new File(tempDirectory, className + ".class");
    }

    static private byte[] allocateByteArrayToHoldClassFile(RandomAccessFile randomAccessFile)
            throws IOException {
        int length = (int) randomAccessFile.length();
        byte[] fullClassFile = new byte[length];
        return fullClassFile;
    }

    private static void writeBytesToFile(byte[] classfileBuffer, File classFile) throws IOException {
        FileOutputStream fileOutputStream = new FileOutputStream(classFile);
        fileOutputStream.write(classfileBuffer);
        closeIgnoringIoException(fileOutputStream);
    }

    public static File createTemporaryDirectory(String name) throws IOException {
        File tempDirectory = new File(name);

        if (tempDirectory.exists() && tempDirectory.isDirectory())
            clearAllFiles(tempDirectory);

        if (tempDirectory.exists())
            tempDirectory.delete();

        tempDirectory.mkdir();

        return tempDirectory;
    }

    public static void clearAllFiles(File directory) {
        if (directory.exists() && directory.isDirectory()) {
            String[] files = directory.list();
            for (String currentFile : files)
                new File(directory, currentFile).delete();
        }
    }

    private static void closeIgnoringIoException(Closeable closeable) {
        try {
            if (closeable != null)
                closeable.close();
        } catch (IOException ignore) {
        }
    }

    public static void removeDirectory(File tempDirectory) {
        clearAllFiles(tempDirectory);
        tempDirectory.delete();
    }

    public static void removeFile(File file) {
        if (file.exists() && !file.isFile())
            file.delete();

    }
}
